package app.core;

import app.core.enums.MessageType;
import app.core.model.IMessage;
import app.core.model.impl.Message;
import app.core.thread.ClientRunnable;
import app.core.thread.MyRunnable;
import app.core.thread.ThreadUtil;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;


/**
 * @author Guo.Yang
 * @version 1.0
 * @date 2023/1/15 17:13
 */
public class Client {

    private Socket socket;
    private boolean start = false;
    private String name = null;
    /**
     * 线程池管理器
     */
    private static ExecutorService executors = ThreadUtil.createExecutorService();
    public Client(String ip,int port){
        try {
            this.socket = new Socket(ip,port);
        } catch (IOException e) {
            System.out.println("服务器无响应...");
        }
    }

    public void accept(Consumer<Message> consumer){
        if (!start){
            start = true;
            executors.execute(new ClientRunnable(socket, consumer));
        }
    }

    public boolean sendAll(String message){
        Message send = new Message();
        send.setMessage(message);
        try {
            send(send,MessageType.ALL);
            return true;
        } catch (IOException e) {
            System.out.println("发送失败:"+ e.getMessage());
            return false;
        }

    }

    public boolean send(String message,String who){
        Message send = new Message();
        send.setMessage(message);
        send.setData("who", who);

        try {
            send(send,MessageType.ORDINARY);
            return true;
        } catch (IOException e) {
            System.out.println("发送失败:"+ e.getMessage());
            return false;
        }
    }

    private void send(Message message, MessageType type) throws IOException {
        OutputStream output = socket.getOutputStream();
        message.setData(IMessage.TYPE,type.name());
        if (name != null){
            message.setData(IMessage.NAME, name);
        }
        output.write(message.toString().getBytes(MyRunnable.CHAR_SET));
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isLink(){
        return  socket != null && socket.isConnected();
    }
}
